#pragma once
#include "rbtree.hpp"

namespace test
{

template<class K, class Compare = less<K>>
class set
{
private:
public:
    struct KeyOfVal
    {
        const K& operator()(const K& key)
        {
            return key;
        }
    };

public:
    typedef rb_tree<K, K, KeyOfVal, Compare> rep_type;
    typedef typename rep_type::const_iterator iterator; // use const iter
    typedef typename rep_type::const_iterator const_iterator;

public:
    pair<iterator, bool> insert(const K& key)
    {
        return _t.insert(key); // normal iter can't be const iter
    }

    iterator find(const K& key)
    {
        return _t.find(key);
    }

    void inorder()
    {
        _t.inorder();
    }

public:
    iterator begin()
    {
        return _t.begin();
    }

    iterator end()
    {
        return _t.end();
    }

private:
    rb_tree<K, K, KeyOfVal, Compare> _t;
};

void test_set_1()
{
    set<int> s1;
    s1.insert(3);
    s1.insert(4);
    s1.insert(4);
    s1.insert(8);
    s1.insert(1);
    s1.insert(9);
    s1.insert(9);
    s1.insert(2);

    set<int>::iterator it = s1.begin();
    while (it != s1.end())
    {
        // (*it)++;
        cout << *it << " ";
        ++it;
    }
    cout << endl;
    // 1 2 3 4 8 9

    for (auto& e : s1)
    {
        // e += 1;
        cout << e << " ";
    }
    cout << endl;

}

void test_set_2()
{
    int a[] = {16, 3, 7, 11, 9, 26, 18, 14, 15};
    int b[] = {4, 2, 6, 1, 3, 5, 15, 7, 16, 14};

    set<int> s1;
    set<int> s2;
    for (auto e : a)
    {
        s1.insert(e);
    }

    for (auto e : b)
    {
        s2.insert(e);
    }

    s1.inorder();
    s2.inorder();

    set<int>::iterator it = s1.end();
}

}